﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace SYT.AliApiHandle
{
    public class ApiHelp
    {
        private static int _timeout = 100000;
        //应用密钥
        private static string client_secret = System.Configuration.ConfigurationManager.AppSettings["AppSecret"].ToString();
        private static readonly string DefaultUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
        #region 计算数字签名

        //计算数字签名方法
        public static string dengsign(Dictionary<string, string> paramDic)
        {

            byte[] signatureKey = Encoding.UTF8.GetBytes(client_secret);
            List<string> list = new List<string>();
            foreach (KeyValuePair<string, string> kv in paramDic)
            {
                list.Add(kv.Key + kv.Value);
            }
            list.Sort();
            string tmp = "";
            foreach (string kvstr in list)
            {
                tmp = tmp + kvstr;
            }

            HMACSHA1 hmacsha1 = new HMACSHA1(signatureKey);
            hmacsha1.ComputeHash(Encoding.UTF8.GetBytes(tmp));
            byte[] hash = hmacsha1.Hash;
            return BitConverter.ToString(hash).Replace("-", string.Empty).ToUpper();
        }

        //paramDic: 请求参数，即queryString + request body 中的所有参数
        public static string sign(string urlPath, Dictionary<string, string> paramDic)
        {
            //把前两步的字符串拼起来，得到s = param2/1/system/currentTime/850156a2b1 
            //然后 Signature=uppercase (hex (hmac_sha1 (s, secretKey)) 得到签名 
            int i1 = urlPath.IndexOf("param2");
            int i2 = urlPath.Length;
            string urlP = urlPath.Substring(i1, i2 - i1);

            byte[] signatureKey = Encoding.UTF8.GetBytes(client_secret);
            List<string> list = new List<string>();
            foreach (KeyValuePair<string, string> kv in paramDic)
            {
                if (kv.Key != "imageBytes")   //图片不签名
                {
                    list.Add(kv.Key + kv.Value);
                }
            }
            list.Sort();

            string tmp = "";
            foreach (string kvstr in list)
            {
                tmp = tmp + kvstr;
            }
            tmp = urlP + tmp;  //正确的

            HMACSHA1 hmacsha1 = new HMACSHA1(signatureKey);
            hmacsha1.ComputeHash(Encoding.UTF8.GetBytes(tmp));

            byte[] hash = hmacsha1.Hash;
            return BitConverter.ToString(hash).Replace("-", string.Empty).ToUpper();
        }

        #endregion

        // 执行HTTP POST请求。url：请求地址，parameters：请求参数
        public static string DoPost(string url, IDictionary<string, string> parameters)
        {
            HttpWebRequest req = GetWebRequest(url, "POST");
            req.ContentType = "application/x-www-form-urlencoded;charset=utf-8";

            byte[] postData = Encoding.UTF8.GetBytes(BuildQuery(parameters));
            System.IO.Stream reqStream = req.GetRequestStream();
            reqStream.Write(postData, 0, postData.Length);
            reqStream.Close();

            HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();
            Encoding encoding = Encoding.GetEncoding(rsp.CharacterSet);
            return GetResponseAsString(rsp, encoding);
            //return url +"?"+ BuildQuery(parameters);
        }

        // 组装普通文本请求参数。parameters：Key-Value形式请求参数字典
        public static string BuildQuery(IDictionary<string, string> parameters)
        {
            StringBuilder postData = new StringBuilder();
            bool hasParam = false;

            IEnumerator<KeyValuePair<string, string>> dem = parameters.GetEnumerator();
            while (dem.MoveNext())
            {
                string name = dem.Current.Key;
                string value = dem.Current.Value;
                // 忽略参数名或参数值为空的参数
                if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
                {
                    if (hasParam)
                    {
                        postData.Append("&");
                    }

                    postData.Append(name);
                    postData.Append("=");
                    postData.Append(HttpUtility.UrlEncode(value, Encoding.UTF8));
                    hasParam = true;
                }
            }

            return postData.ToString();
        }

        // 把响应流转换为文本。rsp：响应流对象，encoding：编码方式
        public static string GetResponseAsString(HttpWebResponse rsp, Encoding encoding)
        {
            System.IO.Stream stream = null;
            StreamReader reader = null;

            try
            {
                stream = rsp.GetResponseStream();
                // 以字符流的方式读取HTTP响应
                reader = new StreamReader(stream, encoding);
                return reader.ReadToEnd();
            }
            finally
            {
                // 释放资源
                if (reader != null) reader.Close();
                if (stream != null) stream.Close();
                if (rsp != null) rsp.Close();
            }
        }

        public static HttpWebRequest GetWebRequest(string url, string method)
        {
            HttpWebRequest req = null;
            if (url.Contains("https"))
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                req = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
            }
            else
            {
                req = (HttpWebRequest)WebRequest.Create(url);
            }

            req.ServicePoint.Expect100Continue = false;
            req.Method = method;
            req.KeepAlive = true;
            req.UserAgent = "Top4Net";
            req.Timeout = _timeout;

            return req;
        }

        //直接确认，否则打不开
        public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true;
        }

        //访问数据
        public static string goRun(string apiName, Dictionary<string, string> paramDic, string access_token)
        {
            string client_id = System.Configuration.ConfigurationManager.AppSettings["Appkey"].ToString();

            string urlStr = "http://gw.open.1688.com/openapi/param2/1/" + apiName + "/" + client_id + "";
            if (!paramDic.ContainsKey("access_token"))
            {
                paramDic.Add("access_token", access_token);
            }
            if (paramDic.ContainsKey("_aop_signature"))
            {
                paramDic.Remove("_aop_signature");
            }
            string signa = sign(urlStr, paramDic);
            paramDic.Add("_aop_signature", signa);

            //return urlStr;
            return DoPosts(urlStr, paramDic);
        }

        //请求阿里接口总处理方法。
        public static string RunHttps(string apiName, Dictionary<string, string> paramDic, string access_token, string method)
        {
            string client_id = System.Configuration.ConfigurationManager.AppSettings["Appkey"].ToString();

            string urlStr = apiName + "/" + client_id + "";
            if (!paramDic.ContainsKey("access_token"))
            {
                paramDic.Add("access_token", access_token);
            }

            string signa = sign(urlStr, paramDic);
            if (!paramDic.ContainsKey("_aop_signature"))
            {
                paramDic.Add("_aop_signature", signa);
            }

            HttpWebRequest request = null;
            //HTTPSQ请求  
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
            request = WebRequest.Create(urlStr) as HttpWebRequest;
            request.ProtocolVersion = HttpVersion.Version10;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.UserAgent = DefaultUserAgent;

            byte[] postData = Encoding.UTF8.GetBytes(BuildQuery(paramDic));
            using (Stream stream = request.GetRequestStream())
            {
                stream.Write(postData, 0, postData.Length);
            }

            try
            {
                var rsp = request.GetResponse() as HttpWebResponse;
                return GetResponseAsString(rsp, Encoding.UTF8);
            }
            catch (Exception ex)
            {

                return ex.Message;
            }
        }

        //跟据参数返回数据。
        public static string DoPosts(string url, IDictionary<string, string> parameters)
        {
            HttpWebRequest req = GetWebRequest(url, "POST");
            req.ContentType = "application/x-www-form-urlencoded;charset=utf-8";

            byte[] postData = Encoding.UTF8.GetBytes(BuildQuery(parameters));
            System.IO.Stream reqStream = req.GetRequestStream();
            reqStream.Write(postData, 0, postData.Length);
            reqStream.Close();

            HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();
            Encoding encoding = Encoding.GetEncoding(rsp.CharacterSet);
            return GetResponseAsString(rsp, encoding);
            //return url +"?"+ BuildQuery(parameters);
        }

        // 将字符串转换为日期
        public static DateTime ConvertTime(string strtime)
        {
            strtime = strtime.Substring(0, 4) + "/" + strtime.Substring(4, 2) + "/" + strtime.Substring(6, 2) + " " + strtime.Substring(8, 2) + ":" + strtime.Substring(10, 2) + ":" + strtime.Substring(12, 2);

            DateTime datetime = Convert.ToDateTime(strtime);
            return datetime;
        }

        //一般请求，不需要授权，不需要签名。
        public static string RunHttpsProtype(string urlStr)
        {
            HttpWebRequest request = null;
            //HTTPSQ请求  
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
            request = WebRequest.Create(urlStr) as HttpWebRequest;
            request.ProtocolVersion = HttpVersion.Version10;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.UserAgent = DefaultUserAgent;

            var rsp = request.GetResponse() as HttpWebResponse;
            return GetResponseAsString(rsp, Encoding.UTF8);
        }
        //一般请求，不需要授权，但需要签名。
        public static string RunHttpQianming(string apiName, Dictionary<string, string> paramDic)
        {
            string client_id = System.Configuration.ConfigurationManager.AppSettings["Appkey"].ToString();

            string urlStr = apiName + "/" + client_id + "";

            string signa = sign(urlStr, paramDic);
            if (!paramDic.ContainsKey("_aop_signature"))
            {
                paramDic.Add("_aop_signature", signa);
            }

            HttpWebRequest request = null;
            //HTTPSQ请求  
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
            request = WebRequest.Create(urlStr) as HttpWebRequest;
            request.ProtocolVersion = HttpVersion.Version10;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.UserAgent = DefaultUserAgent;

            byte[] postData = Encoding.UTF8.GetBytes(BuildQuery(paramDic));
            using (Stream stream = request.GetRequestStream())
            {
                stream.Write(postData, 0, postData.Length);
            }
            var rsp = request.GetResponse() as HttpWebResponse;
            return GetResponseAsString(rsp, Encoding.UTF8);

        }

        //一般请求，需要授权，但不需要签名。
        public static string RunHttpsAccess(string apiName, Dictionary<string, string> paramDic, string access_token, string method)
        {
            string client_id = System.Configuration.ConfigurationManager.AppSettings["Appkey"].ToString();

            string urlStr = apiName + "/" + client_id + "";
            if (!paramDic.ContainsKey("access_token"))
            {
                paramDic.Add("access_token", access_token);
            }


            HttpWebRequest request = null;
            //HTTPSQ请求  
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
            request = WebRequest.Create(urlStr) as HttpWebRequest;
            request.ProtocolVersion = HttpVersion.Version10;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.UserAgent = DefaultUserAgent;

            byte[] postData = Encoding.UTF8.GetBytes(BuildQuery(paramDic));
            using (Stream stream = request.GetRequestStream())
            {
                stream.Write(postData, 0, postData.Length);
            }
            var rsp = request.GetResponse() as HttpWebResponse;
            return GetResponseAsString(rsp, Encoding.UTF8);
        }
        //****************************************************************************************************
        //****************************************************************************************************
        //****************************************************************************************************
        //****************************************************************************************************
        //****************************************************************************************************
        //****************************************************************************************************
        //****************************************************************************************************
        //****************************************************************************************************
        /// <summary>
        /// 请求阿里Api,不需要授权，但需要签名。
        /// </summary>
        /// <param name="apiName"></param>
        /// <param name="paramDic"></param>
        /// <param name="access_token"></param>
        /// <param name="method"></param>
        /// <returns></returns>
        public static string RequestAliApi(string apiName, Dictionary<string, object> paramDic)
        {
            string client_id = System.Configuration.ConfigurationManager.AppSettings["Appkey"].ToString();

            string urlStr = apiName + "/" + client_id + "";

            string signa = Mysign(urlStr, paramDic);
            if (!paramDic.ContainsKey("_aop_signature"))
            {
                paramDic.Add("_aop_signature", signa);
            }

            HttpWebRequest request = null;
            //HTTPSQ请求  
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
            request = WebRequest.Create(urlStr) as HttpWebRequest;
            request.ProtocolVersion = HttpVersion.Version10;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.UserAgent = DefaultUserAgent;

            byte[] postData = Encoding.UTF8.GetBytes(MyBuildQuery(paramDic));
            using (Stream stream = request.GetRequestStream())
            {
                stream.Write(postData, 0, postData.Length);
            }
            var rsp = request.GetResponse() as HttpWebResponse;
            return GetResponseAsString(rsp, Encoding.UTF8);
        }

        public static string Mysign(string urlPath, Dictionary<string, object> paramDic)
        {
            //把前两步的字符串拼起来，得到s = param2/1/system/currentTime/850156a2b1 
            //然后 Signature=uppercase (hex (hmac_sha1 (s, secretKey)) 得到签名 
            int i1 = urlPath.IndexOf("param2");
            int i2 = urlPath.Length;
            string urlP = urlPath.Substring(i1, i2 - i1);

            byte[] signatureKey = Encoding.UTF8.GetBytes(client_secret);
            List<string> list = new List<string>();
            foreach (KeyValuePair<string, object> kv in paramDic)
            {
                if (kv.Key != "imageBytes")   //图片不签名
                {
                    list.Add(kv.Key + kv.Value);
                }
            }
            list.Sort();

            string tmp = "";
            foreach (string kvstr in list)
            {
                tmp = tmp + kvstr;
            }
            tmp = urlP + tmp;  //正确的

            HMACSHA1 hmacsha1 = new HMACSHA1(signatureKey);
            hmacsha1.ComputeHash(Encoding.UTF8.GetBytes(tmp));

            byte[] hash = hmacsha1.Hash;
            return BitConverter.ToString(hash).Replace("-", string.Empty).ToUpper();
        }

        public static string MyBuildQuery(IDictionary<string, object> parameters)
        {
            StringBuilder postData = new StringBuilder();
            bool hasParam = false;

            IEnumerator<KeyValuePair<string, object>> dem = parameters.GetEnumerator();
            while (dem.MoveNext())
            {
                string name = dem.Current.Key;
                object value = dem.Current.Value;
                // 忽略参数名或参数值为空的参数
                if (!string.IsNullOrEmpty(name) && value != null && value != "")
                {
                    if (hasParam)
                    {
                        postData.Append("&");
                    }

                    postData.Append(name);
                    postData.Append("=");
                    postData.Append(HttpUtility.UrlEncode((string)value, Encoding.UTF8));
                    hasParam = true;
                }
            }

            return postData.ToString();
        }



    }

}
